#include <regx52.h>
sbit DQ = P3^7;  // 数据引脚

/**
 * @brief 初始化OneWire总线，进行复位和准备通信。
 *
 * 该函数会通过发送复位脉冲和读取DQ引脚来检查设备是否响应。
 *
 * @return 返回DQ引脚的状态（0或1），用于表示是否成功接收到设备响应。
 */
unsigned char WireInit()
{
    unsigned char DQ_Count;
    unsigned char i;
    EA=0;  // 关闭总线
    DQ = 1;  // 设置DQ为高电平
    DQ = 0;  // 发送复位信号（将DQ拉低）
    i = 230; while (--i); // 延时500us
    DQ = 1;  // 释放复位信号（将DQ拉高）
    i = 20; while (--i);  // 延时30us
    
    DQ_Count = DQ;  // 读取DQ引脚的状态，检查是否有设备响应
    i = 214; while (--i); // 延时470us
    EA=1;  // 开启总线
    return DQ_Count;  // 返回DQ引脚的状态
}

/**
 * @brief 向OneWire总线写入一个比特。
 *
 * @param Bit 需要写入的比特值（0或1）
 *
 * @return 无
 */
void WireWriteBit(unsigned char Bit)
{
    unsigned char i;
    EA=0;  // 关闭总线
    DQ = 0;  // 先拉低DQ
    i = 4; while (--i);  // 延时
    DQ = Bit;  // 根据传入的比特值设置DQ
    i = 23; while (--i);  // 延时
    DQ = 1;  // 将DQ拉高
    i = 4; while (--i);  // 延时
    EA=1;  // 开启总线
}

/**
 * @brief 从OneWire总线读取一个比特。
 *
 * 该函数通过读取DQ引脚的电平来获取OneWire总线的数据位。
 *
 * @return 返回读取到的比特值（0或1）
 */
unsigned char WireReadBit()
{
    unsigned char ReadBit;
    unsigned char i;
    EA=0;  // 关闭总线
    DQ = 0;  // 拉低DQ
    i = 1; while (--i);  // 延时
    DQ = 1;  // 拉高DQ准备读取数据
    i = 3; while (--i);  // 延时
    
    ReadBit = DQ;  // 读取DQ的电平值，作为数据位
    
    if (DQ == 0)  // 如果DQ为低，则等待31个时钟周期
        i = 31; while (--i);
    EA=1;  // 开启总线
    return ReadBit;  // 返回读取到的比特值
}

/**
 * @brief 向OneWire总线写入一个字节。
 *
 * 该函数通过按位写入方式将字节数据写入OneWire总线。
 *
 * @param Data 需要写入的数据字节
 *
 * @return 无
 */
void WireWrite(unsigned char Data)
{
    unsigned char i = 0;
    
    // 逐位写入数据
    for (i = 0; i < 8; i++)
    {
        WireWriteBit(Data & (0x01 << i));  // 提取每一位并写入
    }
}

/**
 * @brief 从OneWire总线读取一个字节。
 *
 * 该函数通过按位读取方式从OneWire总线读取字节数据。
 *
 * @return 返回读取到的数据字节
 */
unsigned char WireRead()
{
    unsigned char i = 0;
    unsigned char Data = 0x00;
    
    // 逐位读取数据
    for (i = 0; i < 8; i++)
    {
        if (WireReadBit())  // 如果读取到的比特为1，设置相应的位
            Data |= (0x01 << i);
    }
    
    return Data;  // 返回读取到的字节数据
}
